<template>
  <div class="user-management page-container">
    <div class="page-header">
      <div class="header-content">
        <h1 class="page-title">管理员账号</h1>
        <p class="page-subtitle">管理系统用户信息，分配角色权限</p>
      </div>
      <el-button
        v-if="userMenuCodes.includes('administrator:add')"
        type="primary"
        @click="onAddUser"
        class="add-btn"
      >
        <svg class="btn-icon" viewBox="0 0 24 24" fill="currentColor">
          <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
        </svg>
        新增用户
      </el-button>
    </div>

    <div class="content-card">
      <div class="search-section">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索用户名或邮箱"
          class="search-input"
          clearable
        >
          <template #prefix>
            <svg class="search-icon" viewBox="0 0 24 24" fill="currentColor">
              <path
                d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
              />
            </svg>
          </template>
        </el-input>
        <el-select
          v-model="searchStatus"
          placeholder="选择状态"
          clearable
          class="status-select"
        >
          <el-option label="启用" :value="1" />
          <el-option label="锁定" :value="2" />
          <el-option label="删除" :value="3" />
        </el-select>
        <el-button type="primary" @click="handleSearch">搜索</el-button>
        <el-button @click="resetSearch">重置</el-button>
      </div>

      <el-table
        :data="users"
        style="width: 100%"
        class="user-table"
        v-loading="loading"
      >
        <el-table-column type="index" label="序号" width="80" align="center" />
        <el-table-column prop="username" label="用户名" width="150" />
        <el-table-column prop="nickname" label="昵称" width="150" />
        <el-table-column prop="email" label="邮箱" width="200" />
        <el-table-column prop="status" label="状态" width="100">
          <template #default="scope">
            <el-tag :type="getStatusType(scope.row.status)" size="small">
              {{ getStatusText(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <!-- <el-table-column prop="roleNames" label="角色" width="200">
          <template #default="scope">
            <el-tag
              v-for="role in scope.row.roleNames"
              :key="role.id"
              size="small"
              class="role-tag"
            >
              {{ role.roleName }}
            </el-tag>
            <span
              v-if="!scope.row.roleNames || scope.row.roleNames.length === 0"
              class="no-role"
            >
              无角色
            </span>
          </template>
        </el-table-column> -->
        <!-- <el-table-column prop="createdTime" label="创建时间" width="180" /> -->
        <!-- <el-table-column prop="createdByName" label="创建人" width="120" /> -->
        <el-table-column prop="modifiedTime" label="修改时间" width="160" />
        <el-table-column prop="modifiedByName" label="修改人" width="180" />
        <!--  fixed="right" -->
        <el-table-column label="操作" width="300">
          <template #default="scope">
            <div class="action-buttons" v-if="scope.row.status !== 3">
              <el-button
                size="small"
                type="info"
                @click="viewUserDetail(scope.row)"
                class="action-btn"
              >
                详情
              </el-button>
              <el-button
                v-if="userMenuCodes.includes('administrator:modify')"
                size="small"
                type="primary"
                @click="editUser(scope.row)"
                class="action-btn"
              >
                编辑
              </el-button>
              <el-button
                v-if="userMenuCodes.includes('administrator:binding:role')"
                size="small"
                type="success"
                @click="bindRoles(scope.row)"
                class="action-btn"
                :disabled="scope.row.status !== 1"
              >
                绑定角色
              </el-button>
              <el-button
                v-if="userMenuCodes.includes('administrator:delete')"
                size="small"
                type="danger"
                @click="deleteUser(scope.row)"
                class="action-btn"
                :disabled="scope.row.deleteTag !== 1"
              >
                删除
              </el-button>
            </div>
            <span v-else class="deleted-user-text">已删除</span>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 新增/编辑用户对话框 -->
    <el-dialog
      v-model="showAddDialog"
      :title="editingUser ? '编辑用户' : '新增用户'"
      width="500px"
      class="user-dialog"
    >
      <el-form
        ref="userFormRef"
        :model="userForm"
        :rules="userRules"
        label-width="100px"
      >
        <el-form-item label="用户名" prop="username">
          <el-input
            v-model="userForm.username"
            placeholder="请输入用户名"
            :disabled="!!editingUser"
          />
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="userForm.email" placeholder="请输入邮箱" />
        </el-form-item>
        <el-form-item label="昵称" prop="nickname">
          <el-input v-model="userForm.nickname" placeholder="请输入昵称" />
        </el-form-item>
        <el-form-item label="密码" prop="password" v-if="!editingUser">
          <el-input
            v-model="userForm.password"
            type="password"
            placeholder="请输入密码"
            show-password
          />
        </el-form-item>
        <el-form-item label="密码" prop="editPassword" v-if="editingUser">
          <el-input
            v-model="userForm.password"
            type="password"
            placeholder="请输入新密码（不填则不修改）"
            show-password
          />
        </el-form-item>
        <el-form-item label="状态" prop="status" v-if="editingUser">
          <el-select v-model="userForm.status" placeholder="请选择状态">
            <el-option label="启用" :value="1" />
            <el-option label="锁定" :value="2" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showAddDialog = false">取消</el-button>
          <el-button type="primary" @click="saveUser" :loading="saving">
            {{ editingUser ? "更新" : "创建" }}
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 用户详情对话框 -->
    <el-dialog
      v-model="showDetailDialog"
      title="用户详情"
      width="900px"
      class="detail-dialog"
    >
      <div v-if="userDetail" class="user-detail-container">
        <!-- 用户基本信息卡片 -->
        <div class="detail-card">
          <div class="card-header">
            <div class="header-icon">
              <svg
                viewBox="0 0 24 24"
                fill="currentColor"
                width="24"
                height="24"
              >
                <path
                  d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"
                />
              </svg>
            </div>
            <div class="header-content">
              <h3 class="user-title">{{ userDetail.username }}</h3>
              <p class="user-subtitle">
                {{ userDetail.nickname }} • {{ userDetail.email }}
              </p>
            </div>
            <div class="header-status">
              <el-tag :type="getStatusType(userDetail.status)" size="large">
                {{ getStatusText(userDetail.status) }}
              </el-tag>
            </div>
          </div>
        </div>

        <!-- 基本信息 -->
        <div class="detail-section">
          <h4 class="section-title">
            <svg
              viewBox="0 0 24 24"
              fill="currentColor"
              width="16"
              height="16"
              style="margin-right: 8px"
            >
              <path
                d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
              />
            </svg>
            基本信息
          </h4>
          <div class="info-grid">
            <div class="info-item">
              <span class="info-label">用户ID</span>
              <span class="info-value">{{ userDetail.id }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">用户名</span>
              <span class="info-value">{{ userDetail.username }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">昵称</span>
              <span class="info-value">{{ userDetail.nickname }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">邮箱</span>
              <span class="info-value">{{ userDetail.email }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">用户状态</span>
              <span class="info-value">
                <el-tag :type="getStatusType(userDetail.status)" size="small">
                  {{ getStatusText(userDetail.status) }}
                </el-tag>
              </span>
            </div>
            <div class="info-item">
              <span class="info-label">创建时间</span>
              <span class="info-value">{{ userDetail.createdTime }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">创建人</span>
              <span class="info-value">{{ userDetail.createdByName }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">修改时间</span>
              <span class="info-value">{{ userDetail.modifiedTime }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">修改人</span>
              <span class="info-value">{{ userDetail.modifiedByName }}</span>
            </div>
          </div>
        </div>

        <!-- 角色信息 -->
        <div class="detail-section">
          <h4 class="section-title">
            <svg
              viewBox="0 0 24 24"
              fill="currentColor"
              width="16"
              height="16"
              style="margin-right: 8px"
            >
              <path
                d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"
              />
            </svg>
            角色信息 ({{ userDetail.roles?.length || 0 }})
          </h4>
          <div
            v-if="userDetail.roles && userDetail.roles.length > 0"
            class="roles-grid"
          >
            <div
              v-for="role in userDetail.roles"
              :key="role.id"
              class="role-card"
            >
              <div class="role-card-header">
                <div class="role-avatar">
                  <svg
                    viewBox="0 0 24 24"
                    fill="currentColor"
                    width="16"
                    height="16"
                  >
                    <path
                      d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"
                    />
                  </svg>
                </div>
                <div class="role-info">
                  <h5 class="role-name">{{ role.roleName }}</h5>
                  <p class="role-code">{{ role.roleCode }}</p>
                </div>
                <div class="role-status">
                  <el-tag
                    :type="role.isAdmin === 1 ? 'success' : 'info'"
                    size="small"
                  >
                    {{ role.isAdmin === 1 ? "超级管理员" : "普通角色" }}
                  </el-tag>
                </div>
              </div>
              <div class="role-card-body">
                <div class="role-detail-item">
                  <span class="detail-label">角色ID:</span>
                  <span class="detail-value">{{ role.id }}</span>
                </div>
                <div class="role-detail-item">
                  <span class="detail-label">状态:</span>
                  <span class="detail-value">
                    <el-tag
                      :type="role.status === 1 ? 'success' : 'danger'"
                      size="small"
                    >
                      {{ role.status === 1 ? "启用" : "禁用" }}
                    </el-tag>
                  </span>
                </div>
                <div class="role-detail-item">
                  <span class="detail-label">创建时间:</span>
                  <span class="detail-value">{{ role.createdTime }}</span>
                </div>
              </div>
            </div>
          </div>
          <div v-else class="empty-state">
            <el-empty description="暂无绑定角色" :image-size="80" />
          </div>
        </div>

        <!-- 菜单权限 -->
        <div class="detail-section">
          <h4 class="section-title">
            <svg
              viewBox="0 0 24 24"
              fill="currentColor"
              width="16"
              height="16"
              style="margin-right: 8px"
            >
              <path
                d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"
              />
            </svg>
            菜单权限 ({{ getMenuCount(userDetail.menus) }})
          </h4>
          <div
            v-if="userDetail.menus && userDetail.menus.length > 0"
            class="menu-tree-container"
          >
            <el-tree
              :data="userDetail.menus"
              :props="{ label: 'menuName', children: 'children' }"
              node-key="id"
              default-expand-all
              :render-content="renderMenuNode"
              class="permission-tree"
            />
          </div>
          <div v-else class="empty-state">
            <el-empty description="暂无菜单权限" :image-size="80" />
          </div>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showDetailDialog = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 绑定角色对话框 -->
    <el-dialog
      v-model="showRoleDialog"
      title="绑定角色"
      width="800px"
      class="role-dialog"
    >
      <div class="role-binding-container">
        <!-- 用户信息卡片 -->
        <div class="user-info-card">
          <div class="user-info-header">
            <div class="user-avatar">
              <svg
                viewBox="0 0 24 24"
                fill="currentColor"
                width="24"
                height="24"
              >
                <path
                  d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"
                />
              </svg>
            </div>
            <div class="user-info">
              <h3 class="user-name">{{ selectedUser?.username }}</h3>
              <p class="user-details">
                {{ selectedUser?.nickname }} • {{ selectedUser?.email }}
              </p>
              <div class="user-status">
                <el-tag
                  :type="getStatusType(selectedUser?.status || 1)"
                  size="small"
                >
                  {{ getStatusText(selectedUser?.status || 1) }}
                </el-tag>
              </div>
            </div>
          </div>
        </div>

        <!-- 角色选择区域 -->
        <div class="role-selection-section">
          <div class="section-header">
            <h4 class="section-title">
              <svg
                viewBox="0 0 24 24"
                fill="currentColor"
                width="16"
                height="16"
                style="margin-right: 8px"
              >
                <path
                  d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"
                />
              </svg>
              角色选择 ({{ selectedRoles.length }}/{{ allRoles.length }})
            </h4>
            <div class="selection-stats">
              <span class="stat-item">
                <span class="stat-number">{{ selectedRoles.length }}</span>
                <span class="stat-label">已选择</span>
              </span>
              <span class="stat-divider"></span>
              <span class="stat-item">
                <span class="stat-number">{{ allRoles.length }}</span>
                <span class="stat-label">总角色</span>
              </span>
            </div>
          </div>

          <div class="role-grid">
            <el-checkbox-group v-model="selectedRoles">
              <div
                v-for="role in allRoles"
                :key="role.id"
                class="role-card"
                :class="{ disabled: role.isAdmin === 1 }"
              >
                <el-checkbox
                  :label="role.id"
                  :disabled="role.isAdmin === 1"
                  class="role-checkbox"
                >
                  <div class="role-card-content">
                    <div class="role-avatar">
                      <svg
                        viewBox="0 0 24 24"
                        fill="currentColor"
                        width="16"
                        height="16"
                      >
                        <path
                          d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"
                        />
                      </svg>
                    </div>
                    <div class="role-info">
                      <h5 class="role-name">{{ role.roleName }}</h5>
                      <p class="role-code">{{ role.roleCode }}</p>
                      <div class="role-status">
                        <el-tag
                          :type="role.isAdmin === 1 ? 'success' : 'info'"
                          size="small"
                        >
                          {{ role.isAdmin === 1 ? "超级管理员" : "普通角色" }}
                        </el-tag>
                      </div>
                    </div>
                  </div>
                </el-checkbox>
                <div v-if="role.isAdmin === 1" class="disabled-tip">
                  <el-icon><Warning /></el-icon>
                  <span>超管拥有所有权限，不可手动分配</span>
                </div>
              </div>
            </el-checkbox-group>
          </div>

          <!-- 操作提示 -->
          <div class="role-tips">
            <div class="tip-item">
              <el-icon><InfoFilled /></el-icon>
              <span>勾选表示该用户拥有对应角色的权限</span>
            </div>
            <div class="tip-item">
              <el-icon><Check /></el-icon>
              <span>当前已选择 {{ selectedRoles.length }} 个角色</span>
            </div>
          </div>
        </div>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <div class="footer-left">
            <el-button @click="resetRoleSelection" :disabled="bindingSaving">
              <svg
                viewBox="0 0 24 24"
                fill="currentColor"
                width="14"
                height="14"
                style="margin-right: 4px"
              >
                <path
                  d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"
                />
              </svg>
              重置选择
            </el-button>
          </div>
          <div class="footer-right">
            <el-button @click="showRoleDialog = false" :disabled="bindingSaving"
              >取消</el-button
            >
            <el-button
              type="primary"
              @click="saveRoleBinding"
              :loading="bindingSaving"
              class="save-btn"
            >
              <svg
                viewBox="0 0 24 24"
                fill="currentColor"
                width="14"
                height="14"
                style="margin-right: 4px"
              >
                <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" />
              </svg>
              保存绑定
            </el-button>
          </div>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { postWithAuth } from "@/utils/request";

interface User {
  id: string;
  username: string;
  nickname: string;
  email: string;
  status: number;
  deleteTag: number;
  createdBy: string;
  createdByName: string;
  createdTime: string;
  modifiedBy: string;
  modifiedByName: string;
  modifiedTime: string;
  roles: Role[] | null;
  menus: Menu[] | null;
}

interface Role {
  id: string;
  roleCode: string;
  roleName: string;
  isAdmin: number;
  status: number;
  createdTime: string;
  createdBy: string;
  createdByName: string;
  modifiedTime: string;
  modifiedBy: string;
  modifiedByName: string;
  menus: any[] | null;
}

interface Menu {
  id: string;
  menuName: string;
  code: string | null;
  url: string | null;
  icon: string | null;
  menuType: number;
  status: number;
  pid: string;
  createdTime: string;
  createdBy: string;
  createdByName: string | null;
  modifiedTime: string;
  modifiedBy: string;
  modifiedByName: string | null;
  children: Menu[];
}

interface UserForm {
  username: string;
  nickname: string;
  email: string;
  password?: string;
  status: number;
}

interface SearchParams {
  keyword?: string;
  status?: number;
  pageIndex: number;
  pageSize: number;
}

const loading = ref(false);
const saving = ref(false);
const bindingSaving = ref(false);
const showAddDialog = ref(false);
const showDetailDialog = ref(false);
const showRoleDialog = ref(false);
const editingUser = ref<User | null>(null);
const selectedUser = ref<User | null>(null);
const userDetail = ref<User | null>(null);
const searchKeyword = ref("");
const searchStatus = ref<number | null>(null);
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0);
const selectedRoles = ref<string[]>([]);

const users = ref<User[]>([]);

const allRoles = ref<any[]>([]); // 所有角色

const userForm = reactive<UserForm>({
  username: "",
  nickname: "",
  email: "",
  password: "",
  status: 1,
});

const userRules = {
  username: [
    { required: true, message: "请输入用户名", trigger: "blur" },
    { min: 3, max: 20, message: "长度在 3 到 20 个字符", trigger: "blur" },
  ],
  nickname: [
    { required: true, message: "请输入昵称", trigger: "blur" },
    { min: 2, max: 20, message: "长度在 2 到 20 个字符", trigger: "blur" },
  ],
  email: [
    { required: true, message: "请输入邮箱", trigger: "blur" },
    { type: "email", message: "请输入正确的邮箱格式", trigger: "blur" },
  ],
  password: [
    { required: true, message: "请输入密码", trigger: "blur" },
    { min: 6, message: "密码长度不能少于6位", trigger: "blur" },
  ],
  editPassword: [{ min: 6, message: "密码长度不能少于6位", trigger: "blur" }],
};

const userFormRef = ref();

// 权限码集合
const userMenuCodes = ref<string[]>([]);

// 递归提取所有code
function extractCodes(menus: any[]): string[] {
  let codes: string[] = [];
  for (const item of menus) {
    if (item.code) codes.push(item.code);
    if (item.children && item.children.length) {
      codes = codes.concat(extractCodes(item.children));
    }
  }
  return codes;
}

// 获取当前用户菜单权限码
async function fetchUserMenuCodes() {
  try {
    const res = await postWithAuth(
      "/internal/system/manager/getSysUserMenuTree",
      {}
    );
    if (res.code === 0 && Array.isArray(res.data)) {
      userMenuCodes.value = extractCodes(res.data);
    } else {
      userMenuCodes.value = [];
    }
  } catch {
    userMenuCodes.value = [];
  }
}

// 获取用户分页列表
const fetchUsers = async () => {
  loading.value = true;
  try {
    const params: SearchParams = {
      pageIndex: currentPage.value,
      pageSize: pageSize.value,
    };

    if (searchKeyword.value.trim()) {
      params.keyword = searchKeyword.value.trim();
    }

    if (searchStatus.value !== null) {
      params.status = searchStatus.value;
    }

    const response = await postWithAuth(
      "/internal/system/manager/getSysUserPage",
      params
    );

    if (response.code === 0) {
      users.value = response.data.list || [];
      total.value = parseInt(response.data.total) || 0;
    } else {
      ElMessage.error(response.message || "获取用户列表失败");
    }
  } catch (error) {
    console.error("获取用户列表失败:", error);
    ElMessage.error("获取用户列表失败");
  } finally {
    loading.value = false;
  }
};

// 查看用户详情
const viewUserDetail = async (user: User) => {
  try {
    const response = await postWithAuth(
      "/internal/system/manager/getSysUserById",
      {
        id: user.id,
      }
    );

    if (response.code === 0) {
      userDetail.value = response.data;
      showDetailDialog.value = true;
    } else {
      ElMessage.error(response.message || "获取用户详情失败");
    }
  } catch (error) {
    console.error("获取用户详情失败:", error);
    ElMessage.error("获取用户详情失败");
  }
};

// 搜索
const handleSearch = () => {
  currentPage.value = 1;
  fetchUsers();
};

// 重置搜索
const resetSearch = () => {
  searchKeyword.value = "";
  searchStatus.value = null;
  currentPage.value = 1;
  fetchUsers();
};

// 分页大小改变
const handleSizeChange = (val: number) => {
  pageSize.value = val;
  currentPage.value = 1;
  fetchUsers();
};

// 当前页改变
const handleCurrentChange = (val: number) => {
  currentPage.value = val;
  fetchUsers();
};

// 编辑用户
const editUser = (user: User) => {
  editingUser.value = user;
  Object.assign(userForm, {
    username: user.username,
    nickname: user.nickname,
    email: user.email,
    status: user.status,
    password: "",
  });
  showAddDialog.value = true;
};

// 保存用户
const saveUser = async () => {
  if (!userFormRef.value) return;

  try {
    await userFormRef.value.validate();
    saving.value = true;

    if (!editingUser.value) {
      // 新增用户
      const userData: any = {
        username: userForm.username,
        nickname: userForm.nickname,
        email: userForm.email,
        password: userForm.password,
      };

      const response = await postWithAuth(
        "/internal/system/manager/addSysUser",
        userData
      );

      if (response.code === 0) {
        ElMessage.success("用户创建成功");
        showAddDialog.value = false;
        resetForm();
        fetchUsers(); // 刷新列表
      } else {
        ElMessage.error(response.message || "用户创建失败");
      }
    } else {
      // 编辑用户
      const userData: any = {
        id: editingUser.value.id,
        username: userForm.username,
        nickname: userForm.nickname,
        email: userForm.email,
        status: userForm.status,
        password: userForm.password || "", // 如果用户没有填写密码，传空字符串
      };

      const response = await postWithAuth(
        "/internal/system/manager/modifySysUser",
        userData
      );

      if (response.code === 0) {
        ElMessage.success("用户更新成功");
        showAddDialog.value = false;
        resetForm();
        fetchUsers(); // 刷新列表
      } else {
        ElMessage.error(response.message || "用户更新失败");
      }
    }
  } catch (error) {
    console.error("保存用户失败:", error);
    ElMessage.error("保存用户失败");
  } finally {
    saving.value = false;
  }
};

// 删除用户
const deleteUser = async (user: User) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除用户 "${user.username}" 吗？`,
      "确认删除",
      {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }
    );

    const response = await postWithAuth(
      "/internal/system/manager/deleteSysUser",
      {
        id: user.id,
      }
    );

    if (response.code === 0) {
      ElMessage.success("用户删除成功");
      fetchUsers(); // 刷新列表
    } else {
      ElMessage.error(response.message || "用户删除失败");
    }
  } catch (error) {
    if (error !== "cancel") {
      console.error("删除用户失败:", error);
      ElMessage.error("删除用户失败");
    }
  }
};

// 绑定角色
const bindRoles = async (user: User) => {
  selectedUser.value = user;
  showRoleDialog.value = true;
  bindingSaving.value = true;
  try {
    const res = await postWithAuth("/internal/system/manager/rolesWithUser", {
      id: user.id,
    });
    if (res.code === 0 && Array.isArray(res.data)) {
      allRoles.value = res.data;
      selectedRoles.value = res.data
        .filter((r: any) => r.selected)
        .map((r: any) => r.id);
    } else {
      allRoles.value = [];
      selectedRoles.value = [];
      ElMessage.error(res.message || "获取角色列表失败");
    }
  } catch (e) {
    allRoles.value = [];
    selectedRoles.value = [];
    ElMessage.error("获取角色列表失败");
  } finally {
    bindingSaving.value = false;
  }
};

const saveRoleBinding = async () => {
  if (!selectedUser.value) return;
  bindingSaving.value = true;
  try {
    const res = await postWithAuth("/internal/system/manager/addRolesToUser", {
      userId: selectedUser.value.id,
      roleIds: selectedRoles.value,
    });
    if (res.code === 0) {
      ElMessage.success("角色绑定成功");
      showRoleDialog.value = false;
      fetchUsers();
    } else {
      ElMessage.error(res.message || "角色绑定失败");
    }
  } catch (e) {
    ElMessage.error("角色绑定失败");
  } finally {
    bindingSaving.value = false;
  }
};

// 重置角色选择
const resetRoleSelection = () => {
  selectedRoles.value = [];
};

// 重置表单
const resetForm = () => {
  editingUser.value = null;
  Object.assign(userForm, {
    username: "",
    email: "",
    nickname: "",
    password: "",
    status: 1,
  });
  if (userFormRef.value) {
    userFormRef.value.resetFields();
  }
};

const onAddUser = () => {
  editingUser.value = null;
  resetForm();
  showAddDialog.value = true;
};

// 获取状态类型
const getStatusType = (status: number): string => {
  switch (status) {
    case 1:
      return "success";
    case 2:
      return "warning";
    case 3:
      return "danger";
    default:
      return "info";
  }
};

// 获取状态文本
const getStatusText = (status: number): string => {
  switch (status) {
    case 1:
      return "启用";
    case 2:
      return "锁定";
    case 3:
      return "删除";
    default:
      return "未知";
  }
};

// 计算菜单数量
const getMenuCount = (menus: any[] | null): number => {
  if (!menus || !Array.isArray(menus)) return 0;
  const countNodes = (nodes: any[]): number => {
    return nodes.reduce((count, node) => {
      return count + 1 + (node.children ? countNodes(node.children) : 0);
    }, 0);
  };
  return countNodes(menus);
};

// 自定义树节点渲染
const renderMenuNode = (h: any, { data }: any) => {
  let tagType = "info";
  let tagLabel = "";

  if (data.menuType === 1) {
    tagType = "primary";
    tagLabel = "目录";
  } else if (data.menuType === 2) {
    tagType = "success";
    tagLabel = "菜单";
  } else if (data.menuType === 3) {
    tagType = "warning";
    tagLabel = "按钮";
  }

  return h("span", [
    h("span", data.menuName),
    h(
      "el-tag",
      {
        style: { marginLeft: "8px", fontSize: "12px", padding: "2px 8px" },
        props: { size: "small", type: tagType },
      },
      tagLabel
    ),
  ]);
};

// 组件挂载时获取用户列表
onMounted(() => {
  fetchUsers();
  fetchUserMenuCodes();
});
</script>

<style scoped>
.user-management {
  padding: 24px;
  background: #f5f7fa;
  min-height: 100vh;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
}

.header-content {
  flex: 1;
}

.page-title {
  font-size: 28px;
  font-weight: 700;
  color: #2d3748;
  margin: 0 0 8px 0;
}

.page-subtitle {
  color: #718096;
  margin: 0;
  font-size: 16px;
}

.add-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  border-radius: 8px;
  font-weight: 600;
}

.btn-icon {
  width: 16px;
  height: 16px;
}

.content-card {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.search-section {
  display: flex;
  gap: 16px;
  margin-bottom: 24px;
  align-items: center;
}

.search-input {
  flex: 1;
  max-width: 300px;
}

.status-select {
  width: 120px;
}

.deleted-user-text {
  color: #a0aec0;
  font-size: 12px;
  font-style: italic;
}

.search-icon {
  width: 16px;
  height: 16px;
  color: #a0aec0;
}

.user-table {
  margin-bottom: 24px;
}

.role-tag {
  margin-right: 4px;
  margin-bottom: 4px;
}

.no-role {
  color: #a0aec0;
  font-size: 12px;
  font-style: italic;
}

.action-btn {
  margin-right: 4px;
  margin-bottom: 4px;
  padding: 4px 8px;
  font-size: 11px;
}

.action-buttons {
  display: flex;
  align-items: center;
  gap: 2px;
}

.action-buttons .el-button {
  padding: 3px 6px;
  font-size: 13px;
  min-width: auto;
}

.pagination-wrapper {
  display: flex;
  justify-content: center;
  margin-top: 24px;
}

.user-dialog,
.role-dialog,
.detail-dialog {
  border-radius: 12px;
}

.user-detail {
  padding: 16px 0;
}

.detail-section {
  margin-bottom: 24px;
}

.detail-section h4 {
  margin: 0 0 16px 0;
  color: #2d3748;
  font-size: 16px;
  font-weight: 600;
  border-bottom: 2px solid #e2e8f0;
  padding-bottom: 8px;
}

.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 16px;
}

.detail-item {
  display: flex;
  align-items: center;
  padding: 12px;
  background: #f7fafc;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}

.detail-item .label {
  font-weight: 600;
  color: #4a5568;
  min-width: 80px;
  margin-right: 12px;
}

.detail-item .value {
  color: #2d3748;
  flex: 1;
}

.roles-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.role-item {
  padding: 16px;
  background: #f7fafc;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}

.role-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.role-name {
  font-weight: 600;
  color: #2d3748;
  font-size: 14px;
}

.role-code {
  color: #718096;
  font-size: 12px;
}

.role-id {
  color: #718096;
  font-size: 12px;
}

.role-description {
  color: #4a5568;
  font-size: 13px;
  line-height: 1.4;
}

.no-roles {
  text-align: center;
  padding: 40px 20px;
}

.role-binding {
  padding: 16px 0;
}

.current-user {
  background: #f7fafc;
  padding: 16px;
  border-radius: 8px;
  margin-bottom: 24px;
}

.current-user h4 {
  margin: 0 0 8px 0;
  color: #2d3748;
  font-size: 16px;
}

.current-user p {
  margin: 0;
  color: #718096;
  font-size: 14px;
}

.role-list h4 {
  margin: 0 0 16px 0;
  color: #2d3748;
  font-size: 16px;
}

.role-options {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.role-checkbox {
  width: 100%;
  margin: 0;
}

.role-option {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.role-name {
  font-weight: 600;
  color: #2d3748;
}

.role-desc {
  font-size: 12px;
  color: #718096;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

/* 平板端适配 */
@media (max-width: 1024px) {
  .user-management {
    padding: 20px;
  }

  .page-header {
    padding: 20px;
  }

  .page-title {
    font-size: 24px;
  }

  .page-subtitle {
    font-size: 14px;
  }

  .content-card {
    padding: 20px;
  }

  .search-section {
    gap: 12px;
  }

  .search-input {
    max-width: 250px;
  }
}

/* 手机端适配 */
@media (max-width: 768px) {
  .user-management {
    padding: 16px;
  }

  .page-header {
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
    padding: 20px;
  }

  .page-title {
    font-size: 20px;
    margin-bottom: 6px;
  }

  .page-subtitle {
    font-size: 13px;
  }

  .add-btn {
    align-self: flex-start;
    padding: 10px 20px;
  }

  .content-card {
    padding: 16px;
    border-radius: 10px;
  }

  .search-section {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .search-input {
    max-width: none;
  }

  .user-table {
    margin-bottom: 20px;
  }

  /* 表格在手机端的特殊处理 */
  .user-table :deep(.el-table) {
    font-size: 12px;
  }

  .user-table :deep(.el-table th) {
    padding: 8px 4px;
  }

  .user-table :deep(.el-table td) {
    padding: 8px 4px;
  }

  .action-btn {
    margin-right: 4px;
    margin-bottom: 4px;
    padding: 4px 8px;
    font-size: 11px;
  }

  .role-tag {
    font-size: 10px;
    padding: 2px 6px;
  }

  .pagination-wrapper {
    margin-top: 20px;
  }

  .pagination-wrapper :deep(.el-pagination) {
    font-size: 12px;
  }

  .user-dialog,
  .role-dialog {
    width: 90% !important;
    max-width: 400px;
  }

  .role-binding {
    padding: 12px 0;
  }

  .current-user {
    padding: 12px;
    margin-bottom: 20px;
  }

  .current-user h4 {
    font-size: 14px;
  }

  .current-user p {
    font-size: 12px;
  }

  .role-list h4 {
    font-size: 14px;
    margin-bottom: 12px;
  }

  .role-options {
    gap: 8px;
  }

  .role-name {
    font-size: 13px;
  }

  .role-desc {
    font-size: 11px;
  }

  .dialog-footer {
    gap: 8px;
  }

  .dialog-footer .el-button {
    padding: 8px 16px;
    font-size: 13px;
  }
}

/* 小屏手机适配 */
@media (max-width: 480px) {
  .user-management {
    padding: 12px;
  }

  .page-header {
    padding: 16px;
    gap: 12px;
  }

  .page-title {
    font-size: 18px;
  }

  .page-subtitle {
    font-size: 12px;
  }

  .add-btn {
    padding: 8px 16px;
    font-size: 13px;
  }

  .btn-icon {
    width: 14px;
    height: 14px;
  }

  .content-card {
    padding: 12px;
  }

  .search-section {
    gap: 8px;
  }

  .user-table :deep(.el-table) {
    font-size: 11px;
  }

  .user-table :deep(.el-table th) {
    padding: 6px 2px;
  }

  .user-table :deep(.el-table td) {
    padding: 6px 2px;
  }

  .action-btn {
    padding: 3px 6px;
    font-size: 10px;
    margin-right: 2px;
  }

  .role-tag {
    font-size: 9px;
    padding: 1px 4px;
  }

  .user-dialog,
  .role-dialog {
    width: 95% !important;
    max-width: 350px;
  }

  .current-user {
    padding: 10px;
  }

  .current-user h4 {
    font-size: 13px;
  }

  .current-user p {
    font-size: 11px;
  }

  .role-list h4 {
    font-size: 13px;
  }

  .role-name {
    font-size: 12px;
  }

  .role-desc {
    font-size: 10px;
  }
}

/* 横屏手机适配 */
@media (max-height: 500px) and (orientation: landscape) {
  .user-management {
    padding: 12px;
  }

  .page-header {
    padding: 12px 20px;
    margin-bottom: 16px;
  }

  .page-title {
    font-size: 16px;
    margin-bottom: 4px;
  }

  .page-subtitle {
    font-size: 11px;
  }

  .add-btn {
    padding: 6px 12px;
    font-size: 12px;
  }

  .content-card {
    padding: 12px;
  }

  .search-section {
    margin-bottom: 16px;
  }

  .user-table {
    margin-bottom: 16px;
  }

  .pagination-wrapper {
    margin-top: 16px;
  }
}

/* 表格响应式处理 */
@media (max-width: 768px) {
  /* 隐藏某些列在手机端 */
  .user-table :deep(.el-table__body-wrapper) {
    overflow-x: auto;
  }

  /* 确保表格可以横向滚动 */
  .user-table :deep(.el-table) {
    min-width: 1200px;
  }
}

/* 对话框响应式处理 */
@media (max-width: 768px) {
  .user-dialog :deep(.el-dialog__body),
  .role-dialog :deep(.el-dialog__body) {
    padding: 16px;
  }

  .user-dialog :deep(.el-form-item__label),
  .role-dialog :deep(.el-form-item__label) {
    font-size: 13px;
    line-height: 1.4;
  }

  .user-dialog :deep(.el-input__inner),
  .role-dialog :deep(.el-input__inner) {
    font-size: 14px;
  }
}

.user-dialog,
.role-dialog,
.detail-dialog {
  width: 90% !important;
  max-width: 400px;
}

.detail-dialog {
  max-width: 500px;
}

.detail-grid {
  grid-template-columns: 1fr;
  gap: 12px;
}

.detail-item {
  padding: 10px;
}

.detail-item .label {
  min-width: 70px;
  font-size: 13px;
}

.role-item {
  padding: 12px;
}

.role-header {
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}

.role-name {
  font-size: 13px;
}

.role-code {
  font-size: 11px;
}

.role-id {
  font-size: 11px;
}

.role-description {
  font-size: 12px;
}

.role-details {
  margin-top: 8px;
}

.role-info {
  display: flex;
  align-items: center;
  margin-bottom: 4px;
  font-size: 12px;
}

.info-label {
  font-weight: 600;
  color: #4a5568;
  min-width: 60px;
  margin-right: 8px;
}

.info-value {
  color: #2d3748;
}

.menus-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.menu-item {
  padding: 16px;
  background: #f7fafc;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}

.menu-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid #e2e8f0;
}

.menu-name {
  font-weight: 600;
  color: #2d3748;
  font-size: 14px;
}

.menu-id {
  color: #718096;
  font-size: 12px;
}

.menu-details {
  margin-bottom: 12px;
}

.menu-info {
  display: flex;
  align-items: center;
  margin-bottom: 4px;
  font-size: 12px;
}

.menu-children {
  margin-top: 12px;
  padding-left: 16px;
  border-left: 2px solid #e2e8f0;
}

.menu-child {
  padding: 12px;
  background: #ffffff;
  border-radius: 6px;
  margin-bottom: 8px;
  border: 1px solid #e2e8f0;
}

.child-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.child-name {
  font-weight: 600;
  color: #2d3748;
  font-size: 13px;
}

.child-id {
  color: #718096;
  font-size: 11px;
}

.child-details {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.child-info {
  display: flex;
  align-items: center;
  font-size: 11px;
}

.no-menus {
  text-align: center;
  padding: 40px 20px;
}

/* 用户详情弹窗样式 */
.detail-dialog {
  border-radius: 12px;
}

.user-detail-container {
  padding: 0;
}

.detail-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 12px;
  padding: 24px;
  margin-bottom: 24px;
  color: white;
}

.card-header {
  display: flex;
  align-items: center;
  gap: 16px;
}

.header-icon {
  width: 48px;
  height: 48px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

.header-content {
  flex: 1;
}

.user-title {
  margin: 0 0 4px 0;
  font-size: 24px;
  font-weight: 700;
  color: white;
}

.user-subtitle {
  margin: 0;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.8);
}

.header-status {
  margin-left: auto;
}

.detail-section {
  background: white;
  border-radius: 12px;
  border: 1px solid #e2e8f0;
  overflow: hidden;
  margin-bottom: 20px;
}

.section-title {
  margin: 0;
  color: #2d3748;
  font-size: 16px;
  font-weight: 600;
  display: flex;
  align-items: center;
  padding: 20px 24px;
  background: #f8fafc;
  border-bottom: 1px solid #e2e8f0;
}

.info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
  padding: 24px;
}

.info-item {
  display: flex;
  align-items: center;
  padding: 16px;
  background: #f7fafc;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}

.info-label {
  font-weight: 600;
  color: #4a5568;
  min-width: 80px;
  margin-right: 16px;
  font-size: 14px;
}

.info-value {
  color: #2d3748;
  flex: 1;
  font-size: 14px;
}

.roles-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  padding: 24px;
}

.role-card {
  background: #f7fafc;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
  overflow: hidden;
  transition: all 0.3s ease;
}

.role-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.role-card-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  background: #edf2f7;
  border-bottom: 1px solid #e2e8f0;
}

.role-avatar {
  width: 32px;
  height: 32px;
  background: #667eea;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

.role-info {
  flex: 1;
}

.role-name {
  margin: 0 0 2px 0;
  font-size: 14px;
  font-weight: 600;
  color: #2d3748;
}

.role-code {
  margin: 0;
  font-size: 12px;
  color: #718096;
}

.role-status {
  margin-left: auto;
}

.role-card-body {
  padding: 16px;
}

.role-detail-item {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  font-size: 13px;
}

.role-detail-item:last-child {
  margin-bottom: 0;
}

.detail-label {
  font-weight: 600;
  color: #4a5568;
  min-width: 70px;
  margin-right: 12px;
}

.detail-value {
  color: #2d3748;
  flex: 1;
}

.menu-tree-container {
  padding: 24px;
  max-height: 400px;
  overflow-y: auto;
}

.permission-tree {
  border: none;
}

.empty-state {
  padding: 40px 24px;
  text-align: center;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .detail-dialog {
    width: 95% !important;
    max-width: 600px;
  }

  .detail-card {
    padding: 20px;
    margin-bottom: 20px;
  }

  .card-header {
    gap: 12px;
  }

  .header-icon {
    width: 40px;
    height: 40px;
  }

  .user-title {
    font-size: 20px;
  }

  .user-subtitle {
    font-size: 13px;
  }

  .section-title {
    padding: 16px 20px;
    font-size: 14px;
  }

  .info-grid {
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 20px;
  }

  .info-item {
    padding: 12px;
  }

  .info-label {
    min-width: 70px;
    font-size: 13px;
  }

  .info-value {
    font-size: 13px;
  }

  .roles-grid {
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 20px;
  }

  .role-card-header {
    padding: 12px;
  }

  .role-avatar {
    width: 28px;
    height: 28px;
  }

  .role-name {
    font-size: 13px;
  }

  .role-code {
    font-size: 11px;
  }

  .role-card-body {
    padding: 12px;
  }

  .role-detail-item {
    font-size: 12px;
  }

  .detail-label {
    min-width: 60px;
    font-size: 12px;
  }

  .menu-tree-container {
    padding: 20px;
    max-height: 300px;
  }
}

/* 绑定角色弹窗样式 */
.role-dialog {
  border-radius: 12px;
}

.role-binding-container {
  padding: 0;
}

.user-info-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 12px;
  padding: 24px;
  margin-bottom: 24px;
  color: white;
}

.user-info-header {
  display: flex;
  align-items: center;
  gap: 16px;
}

.user-avatar {
  width: 48px;
  height: 48px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

.user-info {
  flex: 1;
}

.user-name {
  margin: 0 0 4px 0;
  font-size: 20px;
  font-weight: 600;
  color: white;
}

.user-details {
  margin: 0 0 8px 0;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.8);
}

.user-status {
  margin-top: 8px;
}

.role-selection-section {
  background: white;
  border-radius: 12px;
  border: 1px solid #e2e8f0;
  overflow: hidden;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  background: #f8fafc;
  border-bottom: 1px solid #e2e8f0;
}

.section-title {
  margin: 0;
  color: #2d3748;
  font-size: 16px;
  font-weight: 600;
  display: flex;
  align-items: center;
}

.selection-stats {
  display: flex;
  align-items: center;
  gap: 16px;
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.stat-number {
  font-size: 18px;
  font-weight: 700;
  color: #667eea;
}

.stat-label {
  font-size: 12px;
  color: #718096;
}

.stat-divider {
  width: 1px;
  height: 24px;
  background: #e2e8f0;
}

.role-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  padding: 24px;
}

.role-card {
  background: #f7fafc;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
  overflow: hidden;
  transition: all 0.3s ease;
  position: relative;
}

.role-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.role-card.disabled {
  opacity: 0.6;
  background: #f1f5f9;
}

.role-checkbox {
  width: 100%;
  margin: 0;
}

.role-card-content {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
}

.role-avatar {
  width: 32px;
  height: 32px;
  background: #667eea;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

.role-info {
  flex: 1;
}

.role-name {
  margin: 0 0 2px 0;
  font-size: 14px;
  font-weight: 600;
  color: #2d3748;
}

.role-code {
  margin: 0 0 8px 0;
  font-size: 12px;
  color: #718096;
}

.role-status {
  margin-top: 4px;
}

.disabled-tip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  background: #fef2f2;
  border-top: 1px solid #e2e8f0;
  font-size: 12px;
  color: #dc2626;
}

.role-tips {
  padding: 16px 24px;
  background: #f7fafc;
  border-top: 1px solid #e2e8f0;
}

.tip-item {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 13px;
  color: #718096;
}

.tip-item:last-child {
  margin-bottom: 0;
}

.tip-item .el-icon {
  color: #667eea;
}

.dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 0 0 0;
  border-top: 1px solid #e2e8f0;
  margin-top: 24px;
}

.footer-left,
.footer-right {
  display: flex;
  gap: 12px;
}

.save-btn {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
}

.save-btn:hover {
  background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .role-dialog {
    width: 95% !important;
    max-width: 600px;
  }

  .user-info-card {
    padding: 20px;
    margin-bottom: 20px;
  }

  .user-info-header {
    gap: 12px;
  }

  .user-avatar {
    width: 40px;
    height: 40px;
  }

  .user-name {
    font-size: 18px;
  }

  .user-details {
    font-size: 13px;
  }

  .section-header {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
    padding: 16px 20px;
  }

  .selection-stats {
    gap: 12px;
  }

  .role-grid {
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 20px;
  }

  .role-card-content {
    padding: 12px;
  }

  .role-avatar {
    width: 28px;
    height: 28px;
  }

  .role-name {
    font-size: 13px;
  }

  .role-code {
    font-size: 11px;
  }

  .role-tips {
    padding: 12px 20px;
  }

  .tip-item {
    font-size: 12px;
  }

  .dialog-footer {
    flex-direction: column;
    gap: 12px;
  }

  .footer-left,
  .footer-right {
    width: 100%;
    justify-content: center;
  }
}
</style>
